package cn.mrcode.fd.utils.mybatis.page;

import java.io.Serializable;
import java.util.List;

/**
 * 分页返回结果对象
 * 
 * @param <T>
 *            返回结果数据类型
 */
public class Page<T> implements Serializable {
	private int pageNo = 1;// 页码，默认是第一页
	private int pageSize = 10;// 每页显示的记录数，默认是10
	private int totalRecord;// 总记录数
	private int totalPage;// 总页数
	private List<T> results;// 对应的当前页记录
	private boolean hasNextPage;

	public void setHasNextPage(boolean hasNextPage) {
		this.hasNextPage = hasNextPage;
	}

	/**
	 * 是否有下一页
	 * 
	 * @return
	 */
	public boolean hasNextPage() {
		return totalPage - pageNo != 0;
	}

	public boolean isHasNextPage() {
		hasNextPage = this.hasNextPage();
		return this.hasNextPage;
	}

	public int getPageNo() {
		return pageNo;
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalRecord() {
		return totalRecord;
	}

	public void setTotalRecord(int totalRecord) {
		this.totalRecord = totalRecord;
		// 在设置总页数的时候计算出对应的总页数，在下面的三目运算中加法拥有更高的优先级，所以最后可以不加括号。
		int totalPage = totalRecord % pageSize == 0 ? totalRecord / pageSize : totalRecord / pageSize + 1;
		this.setTotalPage(totalPage == 0 ? 1 : totalPage);
	}

	public int getTotalPage() {
		return totalPage;
	}

	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}

	public List<T> getResults() {
		return results;
	}

	public void setResults(List<T> results) {
		this.results = results;
	}

	/** 获取开始记录 */
	public int getCacheStart(){
		return (getPageNo() - 1) * getPageSize();
	}
	/** 获取结束记录 */
	public int getCacheEnd(){
		return getCacheStart() + (getPageSize()-1);
	}
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("Page [pageNo=").append(pageNo).append(", pageSize=").append(pageSize).append(", results=")
				.append(results).append(", totalPage=").append(totalPage).append(", totalRecord=").append(totalRecord)
				.append(", hasNextPage=").append(this.hasNextPage()).append("]");
		return builder.toString();
	}

	/**
	 * 打印bootstrap的分页html代码
	 * @param btnNum 指定显示最大的按钮数量，默认为10，最小2
	 * @return
	 */
	public String getBootstrapHtml(int btnNum){
		btnNum = btnNum == 0 ? 2 : btnNum;
		return new PaginationPlugin(getPageNo(),getTotalPage(),btnNum).printBootstrapHtml();
	}

	/**
	 * 分页插件，bootstrap的分页样式
	 */
	private class PaginationPlugin{
		private int currentPage = 1; //当前页
		private int totalPage = 10; //总页数
		private int btnNum = 10; //分页按钮个数
		/*** 上面是可以自定义的值 **/

		/** 下面是计算出来的值 */
		private int firstPage = 1; //第一页
		private int lastPage = 0; //最后一页
		private int start = 0; //开始   1
		private int end = 0; //结束     5
		private int pre = 0; //前一页   1
		private int next = 0; //下一页  3

		/**
		 * 初始化打印html所需要的数据
		 * @param currentPage 当前页
		 * @param totalPage 总页数
		 * @param btnNum 分页条中间最多显示按钮的个数（不包括首尾上下一页的按钮）
		 */
		public PaginationPlugin(int currentPage, int totalPage, int btnNum) {
			this.currentPage = currentPage;
			this.totalPage = totalPage;
			this.btnNum = btnNum;
			this.lastPage  = totalPage;
		}

		/**
		 * 计算打印html所需要的参数，返回 true，则可以打印html
		 * @return
		 */
		private boolean calcu() {
			if (totalPage < 2) {
//				System.out.println("小于2页，不显示分页");
				return false;
			}
			/** 计算开始 **/
			pre = currentPage - 1;
			next = currentPage + 1;

			int mid = btnNum / 2; //中间页
			start = currentPage - mid;
			end = currentPage + mid;

			if (start <= 0) { //如果开始小于等于0，那么就从第二页开始
				start = 2;
			}
			if (end >= totalPage) { //如果结束页比总页数大
				end = totalPage;
			}

			if (end - start < btnNum) { //如果按钮个数 不够 指定个数,处理结束往后
//				System.out.println("end:temp:" + end);
				end = end + (btnNum - (end - start));  //让结束点 加上 还少的按钮个数
				if (end >= totalPage) { //如果结束点超过了总页数。那么就让结束点 等于总页数
					end = totalPage;
				}
			}

			if (end - start < btnNum) { //如果按钮个数 还是不够。处理开始往前
//				System.out.println("end:temp:" + end);
				start = start - (btnNum - (end - start));
				if (start < 2) {
					start = 2;
				}
			}

			if (next > totalPage) { //下一页 大于 总页数，那么没有下一页，不用处理上一页了。因为当前页等1的时候，-1，刚好等于0
				next = 0;
			}

			return true;
		}

		/**
		 * 打印bootstrap自带样式的html分页html代码
		 * @return
		 */
		public String printBootstrapHtml() {
			if(!calcu()){
				return null;
			}
/*
        前一页模版
        <li>
            <a pageno="{0}" href="{1}" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        */
			String preTemplate = "<li>\n" +
					"            <a pageno=\"{0}\" href=\"{1}\" aria-label=\"Previous\">\n" +
					"                <span aria-hidden=\"true\">&laquo;</span>\n" +
					"            </a>\n" +
					"        </li>";
			/**
			 *  下一页模版
			 *  <li>
			 <a pageno="{0}" href="{1}" aria-label="Next">
			 <span aria-hidden="true">&raquo;</span>
			 </a>
			 </li>
			 */
			String nextTemplate = "<li>\n" +
					"                <a pageno=\"{0}\" href=\"{1}\" aria-label=\"Next\">\n" +
					"                    <span aria-hidden=\"true\">&raquo;</span>\n" +
					"                </a>\n" +
					"            </li>";
			/**
			 * 中间页，包首页尾巴页
			 * <li><a pageno="{0}" href="{1}">{2}</a></li>
			 */
			String midTemplate = "<li><a pageno=\"{0}\" href=\"{1}\">{2}</a></li>";

			/**
			 * 当前页，包首页尾巴页
			 * <li class="active"><a pageno="{0}" href="{1}">{2}</a></li>
			 */
			String currentMidTemplate = "<li class=\"active\"><a pageno=\"{0}\" href=\"{1}\">{2}</a></li>";
			StringBuffer sb = new StringBuffer();
			sb.append("<ul class=\"pagination\">");
			if (pre != 0) {
				sb.append(handerTemplate(preTemplate,pre+"","javascript:void(0);")).append("\n");
			}
			if (firstPage != 0) {
				if(currentPage == firstPage){
					sb.append(handerTemplate(currentMidTemplate,currentPage+"","javascript:void(0);",currentPage+"")).append("\n");
				}else{
					sb.append(handerTemplate(midTemplate,firstPage+"","javascript:void(0);",firstPage+"")).append("\n");
				}
			}
			for (int i = start; i < end; i++) {
				if(currentPage ==  i){
					sb.append(handerTemplate(currentMidTemplate,currentPage+"","javascript:void(0);",currentPage+"")).append("\n");
				}else {
					sb.append(handerTemplate(midTemplate,i+"","javascript:void(0);",i+"")).append("\n");
				}
			}
			if (lastPage != 0) {
				if(currentPage == lastPage){
					sb.append(handerTemplate(currentMidTemplate,currentPage+"","javascript:void(0);",currentPage+"")).append("\n");
				}else {
					sb.append(handerTemplate(midTemplate, lastPage + "", "javascript:void(0);", lastPage + "")).append("\n");
				}
			}
			if (next != 0) {
				sb.append(handerTemplate(nextTemplate,next+"","javascript:void(0);")).append("\n");
			}
			sb.append("</ul>");
			/*System.out.println("------------------\n");
			System.out.println("当前页:" + currentPage + ",限定按钮个数：" + btnNum);
			System.out.println(sb.toString());

			System.out.println(String.format("上一页：%s,首页：%s,start:%s,end:%s,最后一页：%s,下一页：%s", pre, firstPage, start, end, lastPage, next));*/
			return sb.toString();
		}

		/**
		 * 处理模版
		 * @param template
		 * @param params
		 * @return
		 */
		private String handerTemplate(String template,String... params){
			String result = template;
			for (int i = 0; i < params.length; i++) {
				result = result.replace("{"+i+"}",params[i]);
			}
			return result;
		}
	}
	public static void main(String[] args) {
		Page<Object> page = new Page<>();
		page.setPageNo(2);
		page.setTotalPage(2);

		page.getBootstrapHtml(10);
	}


}
